#include "RingQueue.hpp"
#include "Task.hpp"
#include <cstdlib>
#include <ctime>
#include <pthread.h>
#include <unistd.h>


void* produce_routine(void* args)
{
    // RingQueue<int>* rq = static_cast<RingQueue<int>*>(args);
    RingQueue<Task>* rq = static_cast<RingQueue<Task>*>(args);

    while(true)
    {
        // TODO
        // int data = rand() % 10 + 1;
        // rq->push(data);
        // std::cout << "生产完成，数据为：" << data << std::endl;

        int x = rand() % 100 + 1;
        int y = rand() % 10;
        int opi = rand() % 5;
        Task t(x, y, op[opi], myMath);
        rq->push(t);
        std::cout << pthread_self() << " 生产任务：" << t.toTaskString() << std::endl;

        sleep(1);
    }
}
void* consume_routine(void* args)
{
    RingQueue<Task>* rq = static_cast<RingQueue<Task>*>(args);

    while(true)
    {
        // TODO
        // int data;
        // rq->pop(&data);
        // std::cout << "消费完成，数据为：" << data << std::endl;

        Task t;
        rq->pop(&t);
        std::cout << pthread_self() << " 消费任务：" << t() << std::endl;

        sleep(1);
    }
}

int main()
{
    srand((unsigned int)time(nullptr) ^ pthread_self() ^ 0x16582937);

    // RingQueue<int>* rq = new RingQueue<int>();
    RingQueue<Task>* rq = new RingQueue<Task>();


    // 单生产单消费
    // pthread_t producer, consumer;
    // pthread_create(&producer, nullptr, produce_routine, rq);
    // pthread_create(&consumer, nullptr, consume_routine, rq);

    // // TODO

    // pthread_join(producer, nullptr);
    // pthread_join(consumer, nullptr);

    // 多生产多消费
    pthread_t producer[4], consumer[8];
    for(int i = 0; i < 4; ++i) pthread_create(producer + i, nullptr, produce_routine, rq);
    for(int i = 0; i < 8; ++i) pthread_create(consumer + i, nullptr, consume_routine, rq);

    for(int i = 0; i < 4; ++i) pthread_join(producer[i], nullptr);
    for(int i = 0; i < 8; ++i) pthread_join(consumer[i], nullptr);

    delete rq;

    return 0;
}